package com.qf.service.impl;

import com.qf.entity.SysRole;
import com.qf.entity.SysUser;
import com.qf.entity.SysUserVO;
import com.qf.entity.UserDTO;
import com.qf.mapper.UserMapper;
import com.qf.service.UserService;
import com.qf.utils.JwtUtils;
import com.qf.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.TimeUnit;


@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private JwtUtils jwtUtils;
    @Value("${token.expireTime}")
    private int expireTime;

    @Override
    public SysUser userLogin(SysUser sysUser) {
        return userMapper.userLogin(sysUser);
    }

    @Override
    public List<SysUser> findAll(UserDTO userDTO) {
        return Collections.emptyList();
    }

    @Override
    public int deleteAll(List<Integer> ids) {
        return userMapper.deleteAll(ids);
    }

    @Override
    public int deleteUser(int id) {
        return userMapper.deleteUser(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateUser(SysUserVO sysUserVO) {
        int i2 = 0;
        List<SysRole> roles = sysUserVO.getRoles();
        List<Integer> roleIds = new ArrayList<>();
        roles.forEach(role -> {
            roleIds.add(role.getId());
        });
        //System.out.println(roleIds);
        //删除用户角色表
        int i = userMapper.deleteUserRole(sysUserVO.getId());
        //添加用户角色表
        int i1 = userMapper.addUserRole(sysUserVO.getId(), roleIds);
        if (i >0 && i1 > 0){
            //修改用户表
            i2 = userMapper.updateUser(sysUserVO);
        }
        return i2;
    }

    @Override
    public int addUser(SysUser sysUser) {
        return userMapper.addUser(sysUser);
    }





    @Override
    public String login(String username, String password) {
        // 用户验证
        Authentication authentication = null;
        try {
            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
            authentication = authenticationManager
                    .authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                throw new RuntimeException("用户认证失败");
            } else {
                throw new RuntimeException(e.getMessage());
            }
        }
        // 生成jwt
        Map<String, Object> claims = new HashMap<>();
        claims.put("username", authentication.getName());
        // 获取权限对象，用于提取权限数据
        Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
        Set<String> authoritySet = new HashSet<>();
        authorities.forEach(item -> authoritySet.add(item.getAuthority()));
        // 将权限数据放入claims,用于存入jwt
        claims.put("perms", authoritySet);

        //生成用户登录的唯一标识uuid
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        //将uuid存入到token中
        claims.put("uuid", uuid);
        String token = jwtUtils.createToken(claims);

        //利用uuid当键,把token存入到redis中
        redisUtil.setCacheObject("user:key:"+uuid,token,expireTime, TimeUnit.MINUTES);
        return token;
    }


}
